/****************************************************************************
**
** Copyright (C) 2010 Tieto Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Tieto Corporation (info.ostrava@tieto.com)
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial Usage
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Tieto.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Tieto gives you certain additional
** rights.  These rights are described in the Tieto Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
** If you have questions regarding the use of this file, please contact
** Tieto at info.ostrava@tieto.com.
** $QT_END_LICENSE$
**
****************************************************************************/

#include <QtGui/QColor>
#include <QDebug>

#include "convolutiontask.h"
#include "convolutionmodel.h"
#include "convolutionmask.h"
#include "image.h"

ConvolutionTask::ConvolutionTask(ConvolutionModel &model, ConvolutionMask &mask, QObject *parent)
    : BackgroundTask(QString(tr("Convolution")), parent),
    _mask(mask),
    _model(model)

{
}

void ConvolutionTask::doRun()
{
    GrayscaleImage srcImage = _model.sourceImage();
    GrayscaleImage dstImage = _model.convolvedImage();
    convolve(srcImage, dstImage, _mask);
    _model.setConvolvedImage(dstImage);
}

void ConvolutionTask::doCancel()
{
    _isCanceled = true;
}

bool ConvolutionTask::convolve(GrayscaleImage& srcImg, GrayscaleImage& dstImg, ConvolutionMask& mask)
{
    int row;
    int col;
    int rowM;
    int colM;
    int rowIndex;
    int colIndex;
    double sumG;
    double sum = 0;

    // calculate sum
    for( rowM = 0; rowM < mask.rows(); rowM++ ) {
        for ( colM = 0; colM < mask.cols(); colM++ ) {
            sum += mask.value(colM, rowM);
        }
    }
    if (sum == 0) {
        qDebug() << "Zero mask";
        return false;
    }

    if( mask.rows() == 0 || mask.cols() == 0 )
    {
        qDebug() << "Empty mask!";
        return false;
    }

    if( srcImg.width() != dstImg.width() || srcImg.height() != dstImg.height() )
    {
        qDebug() << "Convoluted images has different "
                  << "size than input original one!";
        return false;
    }

    // input image size
    QSize size = srcImg.size();

    // mask center
    QPoint maskCenter = QPoint( mask.rows()/2, mask.cols()/2 );

    emit progressRangeChanged(0, size.height());

    // rows <0,height), columns <0,width)
    for( row = 0; row < size.height(); row++ ) {
        for ( col = 0; col < size.width(); col++ ) {
            sumG = 0;
             for( rowM = 0; rowM < mask.rows(); rowM++ ) { // TODO mask
                for ( colM = 0; colM < mask.cols(); colM++ ) {
                    rowIndex = row + rowM - maskCenter.y();
                    colIndex = col + colM - maskCenter.x();

                    if( rowIndex >= 0 && rowIndex < size.height() &&
                        colIndex >= 0 && colIndex < size.width() ) {
                        Grayscale gray = srcImg.grayscale(colIndex, rowIndex);
                        double value = mask.value(colM, rowM);
                        sumG += (double)gray * value;
                  }
                }
            }
            dstImg.setGrayscale(col, row, sumG/sum);
            if (_isCanceled) {
                emit canceled();
                return false;
            }
        }
        emit progressValueChanged(row);
    }
    qDebug() << "Processing done";
    return true;
}

